package com.hulman.oms.service;

import com.hulman.oms.bean.*;
import com.hulman.oms.dao.WorkTaskDao;
import com.hulman.oms.dao.WorkTaskItemDao;
import com.hulman.oms.exception.IoTException;
import com.hulman.oms.util.DateUtil;
import com.hulman.oms.util.SubjectUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author: maxwellens
 */
@Service
public class WorkTaskItemService
{
    private static final String PROCESS_KEY = "work-task";

    private static final String SUB_TAG = "work-task-item";

    /**
     * 审核通过
     */
    private static final Integer AUDIT_OK = 1;

    /**
     * 审核不通过
     */
    private static final Integer AUDIT_NG = 2;

    @Autowired
    private WorkTaskItemDao workTaskItemDao;
    @Autowired
    private WorkTaskDao workTaskDao;
    @Autowired
    private UserService userService;
    @Autowired
    private ProcInstService procInstService;
    @Autowired
    private MsgService msgService;
    @Autowired
    private TaskService taskService;

    public List<WorkTaskItem> findWorkTaskItems(Map<String, Object> map)
    {
        return workTaskItemDao.findWorkTaskItems(map);
    }

    public Integer findWorkTaskItemsCount(Map<String, Object> map)
    {
        return workTaskItemDao.findWorkTaskItemsCount(map);
    }

    public Result findWorkTaskItemsResult(Map<String, Object> map)
    {
        Integer page = (Integer) map.get("page");
        Integer limit = (Integer) map.get("limit");
        if (page != null && limit != null)
        {
            map.put("start", (page - 1) * limit);
            map.put("length", limit);
        }
        int count = workTaskItemDao.findWorkTaskItemsCount(map);
        List<WorkTaskItem> data = workTaskItemDao.findWorkTaskItems(map);
        return new Result(data, count);
    }

    public WorkTaskItem findWorkTaskItemById(Integer id)
    {
        return workTaskItemDao.findWorkTaskItemById(id);
    }

    public void saveWorkTaskItem(WorkTaskItem workTaskItem)
    {
        if (workTaskItem.getId() != null && workTaskItem.getId() != 0)
        {
            workTaskItemDao.updateWorkTaskItem(workTaskItem);
        } else
        {
            workTaskItemDao.insertWorkTaskItem(workTaskItem);
        }
    }

    public void deleteWorkTaskItemById(Integer id)
    {
        workTaskItemDao.deleteWorkTaskItemById(id);
    }

    public void deleteWorkTaskItems(int[] ids)
    {
        workTaskItemDao.deleteWorkTaskItems(ids);
    }

    /**
     * 创建任务项
     *
     * @param workTaskId    任务工单ID
     * @param workTaskNo    任务工单号
     * @param name          任务名称
     * @param executeByName 执行人
     */
    @Transactional(rollbackFor = Exception.class)
    public void create(Integer workTaskId, String workTaskNo, String name, String deviceName, String deviceLocation, String note, String executeByName, String notifyNames)
    {
        User user = SubjectUtil.getUser();
        if (user == null)
        {
            throw new IoTException("用户未登陆");
        }
        User executeBy = userService.findUserByName(executeByName);
        if (executeBy == null)
        {
            throw new IoTException("不存在人员：" + executeByName);
        }
        //创建任务项
        WorkTaskItem workTaskItem = new WorkTaskItem();
        workTaskItem.setWorkTaskId(workTaskId);
        workTaskItem.setWorkTaskNo(workTaskNo);
        workTaskItem.setName(name);
        workTaskItem.setDeviceName(deviceName);
        workTaskItem.setDeviceLocation(deviceLocation);
        workTaskItem.setNote(note);
        workTaskItem.setExecuteById(executeBy.getId());
        workTaskItem.setExecuteByName(executeByName);
        workTaskItem.setNotifyNames(notifyNames);
        workTaskItem.setAuditTimes(0);
        workTaskItem.setState(WorkTaskItem.STATE_CREATED);
        workTaskItemDao.insertWorkTaskItem(workTaskItem);
        WorkTask workTask = workTaskDao.findWorkTaskById(workTaskItem.getWorkTaskId());
        //创建任务
        Task task1 = new Task();
        task1.setProcInstId(workTask.getProcInstId());
        task1.setOwnerId(user.getId());
        task1.setOwnerName(user.getName());
        task1.setName("创建任务项" + workTaskItem.getName());
        task1.setTag(PROCESS_KEY);
        task1.setSubTag(SUB_TAG);
        taskService.createAndCompleteTask(task1);
        //生成任务
        Task task2 = new Task();
        task2.setProcInstId(workTask.getProcInstId());
        task2.setOwnerId(executeBy.getId());
        task2.setOwnerName(executeByName);
        task2.setName("完成任务项");
        task2.setTag(PROCESS_KEY);
        task2.setSubTag(SUB_TAG);
        task2.setFormKey(workTaskItem.getId().toString());
        task2.addExtra("工单号", workTask.getNo());
        task2.addExtra("任务项名称", workTaskItem.getName());
        task2.addExtra("设施设备", workTaskItem.getDeviceName());
        taskService.addTask(task2);
        task2.setPath("/pages/work-task/item?taskId=" + task2.getId());
        taskService.saveTask(task2);
        msgService.sendMsg(task2.toMsg());
        //通知相关人
        String[] notifyUserNames = notifyNames.split(",");
        for (String notifyName : notifyUserNames)
        {
            User notifyUser = userService.findUserByName(notifyName);
            if (notifyUser != null)
            {
                Msg msg = new Msg();
                msg.setTitle("新的任务项");
                msg.addItem("任务项名称", name);
                msg.addItem("备注", note);
                msg.setType(Msg.TYPE_OM);
                msg.setPath("/pages/work-task/item?id=" + workTaskItem.getId());
                msg.setCreateTime(new Date());
                msg.setState(Msg.STATE_UNREAD);
                msg.setOwnerId(notifyUser.getId());
                msg.setOwnerName(notifyUser.getName());
                msgService.sendMsg(msg);
            }
        }
    }

    /**
     * 任务工单ID
     *
     * @param id
     */
    @Transactional(rollbackFor = Exception.class)
    public void execute(Integer id)
    {
        User user = SubjectUtil.getUser();
        if (user == null)
        {
            throw new IoTException("用户未登陆");
        }
        WorkTaskItem workTaskItem = workTaskItemDao.findWorkTaskItemById(id);
        WorkTask workTask = workTaskDao.findWorkTaskById(workTaskItem.getWorkTaskId());
        workTaskItem.setStartTime(new Date());
        workTaskItem.setState(WorkTaskItem.STATE_EXECUTING);
        workTaskItemDao.updateWorkTaskItem(workTaskItem);

        Task task = new Task();
        task.setProcInstId(workTask.getProcInstId());
        task.setOwnerId(user.getId());
        task.setOwnerName(user.getName());
        task.setName("执行任务");
        task.setTag(PROCESS_KEY);
        task.setSubTag(SUB_TAG);
        task.addExtra("设施设备", workTaskItem.getDeviceName());
        taskService.createAndCompleteTask(task);
    }

    /**
     * 暂存工单
     *
     * @param id         任务项ID
     * @param tools      工具
     * @param materials  材料
     * @param imgs       照片
     * @param completion 完成情况
     */
    @Transactional(rollbackFor = Exception.class)
    public void save(Integer id, String vehicle, String driver, String tools, String materials, String imgs, String completion)
    {
        WorkTaskItem workTaskItem = workTaskItemDao.findWorkTaskItemById(id);
        workTaskItem.setVehicle(vehicle);
        workTaskItem.setDriver(driver);
        workTaskItem.setTools(tools);
        workTaskItem.setMaterials(materials);
        workTaskItem.setImgs(imgs);
        workTaskItem.setCompletion(completion);
        workTaskItemDao.updateWorkTaskItem(workTaskItem);
    }

    /**
     * 完成工单
     *
     * @param taskId     任务ID
     * @param id         任务项ID
     * @param tools      工具
     * @param materials  材料
     * @param location   位置
     * @param imgs       照片
     * @param completion 完成情况
     */

    @Transactional(rollbackFor = Exception.class)
    public void complete(Integer taskId, Integer id, String vehicle, String driver, String tools, String materials, String deviceName, String deviceLocation, String imgs, String completion)
    {
        WorkTaskItem workTaskItem = workTaskItemDao.findWorkTaskItemById(id);
        WorkTask workTask = workTaskDao.findWorkTaskById(workTaskItem.getWorkTaskId());
        workTaskItem.setVehicle(vehicle);
        workTaskItem.setDriver(driver);
        workTaskItem.setTools(tools);
        workTaskItem.setMaterials(materials);
        workTaskItem.setDeviceName(deviceName);
        workTaskItem.setDeviceLocation(deviceLocation);
        workTaskItem.setImgs(imgs);
        workTaskItem.setCompletion(completion);
        workTaskItem.setEndTime(new Date());
        workTaskItem.setState(WorkTaskItem.STATE_AUDITING);
        workTaskItemDao.updateWorkTaskItem(workTaskItem);
        //完成本次任务
        taskService.createAndCompleteTask(taskId);
        //通知负责人已完成
        Msg msg = new Msg();
        msg.setType(Msg.TYPE_OM);
        msg.setTitle("任务已完成");
        msg.setOwnerId(workTask.getCreateById());
        msg.setOwnerName(workTask.getCreateByName());
        msg.addItem("任务名称", workTaskItem.getName());
        msg.addItem("完成情况", workTaskItem.getCompletion());
        msg.addItem("完成人", workTaskItem.getExecuteByName());
        msg.addItem("完成时间", DateUtil.toDate(workTaskItem.getEndTime()));
        msgService.sendMsg(msg);
    }

    /**
     * 审核
     *
     * @param id           任务项ID
     * @param auditResult  审核结果
     * @param auditComment 审核意见
     */
    @Transactional(rollbackFor = Exception.class)
    public void audit(Integer id, Integer auditResult, String auditComment)
    {
        User user = SubjectUtil.getUser();
        if (user == null)
        {
            throw new IoTException("用户未登陆");
        }
        WorkTaskItem workTaskItem = workTaskItemDao.findWorkTaskItemById(id);
        WorkTask workTask = workTaskDao.findWorkTaskById(workTaskItem.getWorkTaskId());
        workTaskItem.setAuditResult(auditResult);
        workTaskItem.setAuditComment(auditComment);
        workTaskItem.setAuditTimes(workTaskItem.getAuditTimes() + 1);
        //审核通过
        if (auditResult == AUDIT_OK)
        {
            workTaskItem.setState(WorkTaskItem.STATE_AUDITED);
            Task task = new Task();
            task.setProcInstId(workTask.getProcInstId());
            task.setOwnerId(user.getId());
            task.setOwnerName(user.getName());
            task.setName("任务项审核通过");
            task.setTag(PROCESS_KEY);
            task.setSubTag(SUB_TAG);
            taskService.createAndCompleteTask(task);
        }
        //审核不通过
        else if (auditResult == AUDIT_NG)
        {
            workTaskItem.setState(WorkTaskItem.STATE_EXECUTING);
            //创建新的任务
            Task task = new Task();
            task.setProcInstId(workTask.getProcInstId());
            task.setOwnerId(workTaskItem.getExecuteById());
            task.setOwnerName(workTaskItem.getExecuteByName());
            task.setName("任务项审核不通过");
            task.setTag(PROCESS_KEY);
            task.setSubTag(SUB_TAG);
            task.setFormKey(workTaskItem.getId().toString());
            task.addExtra("任务名称", workTaskItem.getName());
            task.addExtra("审核意见", workTaskItem.getAuditComment());
            taskService.addTask(task);
            task.setPath("/pages/work-task/item?taskId=" + task.getId());
            taskService.saveTask(task);
            msgService.sendMsg(task.toMsg());
        }
        workTaskItemDao.updateWorkTaskItem(workTaskItem);
    }

    /**
     * 撤销
     *
     * @param id
     */
    @Transactional(rollbackFor = Exception.class)
    public void cancel(Integer id)
    {
        //删除任务项
        WorkTaskItem workTaskItem = workTaskItemDao.findWorkTaskItemById(id);
        workTaskItemDao.deleteWorkTaskItemById(id);
        //删除关联任务
        Map<String, Object> map = new HashMap<>();
        map.put("subTag", SUB_TAG);
        map.put("name", "完成任务项");
        map.put("formKey", workTaskItem.getId().toString());
        List<Task> tasks = taskService.findTasks(map);
        for (Task task : tasks)
        {
            taskService.deleteTaskById(task.getId());
        }
    }

}
